package com.gaoyi.websocket.common;

import com.alibaba.fastjson.JSON;
import com.gaoyi.websocket.entity.Message;
import com.gaoyi.websocket.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ConcurrentHashMap;

import static com.gaoyi.websocket.controller.ChatController.ASSIST;
import static com.gaoyi.websocket.controller.ChatController.SERVER;
import static com.gaoyi.websocket.service.impl.MessageServiceImpl.LATEST_MSG;
import static com.gaoyi.websocket.service.impl.MessageServiceImpl.OWNER;

@ServerEndpoint(value = "/websocket/{uuid}")
@Component
@Slf4j
public class GaoYiWebSocketServer {

    private static RedisUtils redisUtils;
    private static Message m = new Message();

    @Autowired
    public void setRedisUtil(RedisUtils redisUtils) {
        GaoYiWebSocketServer.redisUtils = redisUtils;
    }

    public static final DateTimeFormatter time = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm");

    //线程安全的map保存游客的id和session
    public static final ConcurrentHashMap<String,Session> userPools = new ConcurrentHashMap<String,Session>();

    @OnOpen
    public void onOpen(Session session, @PathParam("uuid")String uuid) throws IOException {

        //方式一：以jsessionId做为游客的id，但是在前后端分离项目中，浏览器不会保存cookie，jsessionId会不停的改变。
        /**这里不从config中拿sessionId，直接从session中拿，在生成session时将endpointConfig中的userProperties全部加入了session中
        HttpSession hs = (HttpSession) (session.getUserProperties()).get("sessionId");
        String sessionId = config.getUserProperties().get("sessionId").toString();
        String sessionId = hs.getId();*/

        //方式二：本项目使用前端随即生存的uuid作为游客id，id储存在localStorage当中，没有就随机生成一个，有就不生成
        if (uuid.equals("GaoYi888")){
            userPools.put("server",session);
            log.info("server  连接成功，当前在线人数：" + userPools.size());

        }else if (uuid.equals("GaoYi777")){
            userPools.put("assist",session);
            log.info("assist 连接成功，当前在线人数：" + userPools.size());

        }else{
            userPools.put(uuid,session);
            log.info(uuid + "  连接成功，当前在线人数：" + userPools.size());
            sendString(session,"连接成功 O(∩_∩)O " + time.format(LocalDateTime.now()));
        }
    }

    //连接关闭时调用的方法
    @OnClose
    public void onClose( @PathParam("uuid") String uuid ){
        if (uuid.equals("GaoYi888")){
            userPools.remove("server");
            log.info("server  断开连接，当前在线人数：" + userPools.size());
        }else if(uuid.equals("GaoYi777")){
            userPools.remove("GaoYi777");
            log.info("assist  断开连接，当前在线人数：" + userPools.size());
        }else {
            /**HttpSession hs = (HttpSession) (session.getUserProperties()).get("sessionId");
            userPools.remove(hs.getId());*/
            userPools.remove(uuid);
            log.info(uuid + "  断开连接，当前在线人数：" + userPools.size());
        }
    }

    //连接出错时调用的方法
    @OnError
    public void onError(Throwable error) {
        error.printStackTrace();
        log.info("连接失败 /(ㄒoㄒ)/~~ " + time.format(LocalDateTime.now()));
    }


    //发送信息
    public void sendString(Session session, String message) throws IOException {
        session.getBasicRemote().sendText(message);
    }

    public void sendInfo(String receiveId, String message) throws IOException {
        Session session = userPools.get(receiveId);
        session.getBasicRemote().sendText(message);
    }


     //系统收到消息时候转发给客服
    @OnMessage
    public void onMessage(String msg) throws IOException{
        Message message= JSON.parseObject(msg, Message.class);
        message.setDate(time.format(LocalDateTime.now()));
        String sendId = message.getSendId();
        String receiveId = message.getReceiveId();
        //如果发送消息的人是客服，消息还是保存到接收游客的id名下，这样前端就能通过游客的 id 获取到所有互动消息
        if (sendId.equals(SERVER)){
            redisUtils.lPush(OWNER + receiveId,message);
            //保存到最近一条消息
            redisUtils.hmSet(LATEST_MSG,receiveId,message);

        }else {
            //发送人是游客
            redisUtils.lPush(OWNER + sendId,message);
            redisUtils.hmSet(LATEST_MSG,sendId,message);
        }

        //推送消息，需要对方在线，不然会空指针
        if (GaoYiWebSocketServer.userPools.containsKey(receiveId)){
            sendInfo(receiveId, JSON.toJSONString(message));
            if (GaoYiWebSocketServer.userPools.containsKey(ASSIST)){
                sendInfo(ASSIST, JSON.toJSONString(message));
            }
        }else if (!receiveId.equals(SERVER)){
            //如果用户不在线，给客服一条提示
            Message m = new Message();
            m.setReceiveId(sendId);
            m.setContent("系统: " + receiveId + " 当前不在线");
            sendInfo(sendId, JSON.toJSONString(m));
        }
    }
}
